#include "NDFFMpegParse.h"
#include <libavcodec/avcodec.h>

NDFFMpegParse::NDFFMpegParse()
{
	m_bInit			= false;
	m_pFmtCtx		= NULL;
	m_nAsIndex		= -1;
	m_nVsIndex		= -1;
}

NDFFMpegParse::~NDFFMpegParse()
{
	if (m_bInit && !m_pFmtCtx)
	{
		av_close_input_file(m_pFmtCtx);
	}
}

bool NDFFMpegParse::Init()
{
	if (!m_bInit)
	{
		av_register_all();
		m_bInit	= true;
		return true;
	}
	return false;
}

bool NDFFMpegParse::OpenFile( const char* szFileName )
{
	if (!m_bInit)
	{
		return false;
	}

	if( 0 != av_open_input_file(&m_pFmtCtx, szFileName, NULL, 0, NULL))
	{
		return false;
	}
	return true;
}

bool NDFFMpegParse::CanProcessFile()
{
	return FindStreamInfo();
}

bool NDFFMpegParse::FindStreamInfo()
{
	if (!m_pFmtCtx)
	{
		return false;
	}

	if (av_find_stream_info(m_pFmtCtx) < 0)
	{
		return false;
	}

	unsigned int i = 0;
	for (i = 0; i < m_pFmtCtx->nb_streams; ++i)
	{
		AVCodecContext *enc = m_pFmtCtx->streams[i]->codec;
		switch(enc->codec_type)
		{
		case CODEC_TYPE_AUDIO:
			m_nAsIndex = i;
			m_header.AudioHeader.m_nChannles	= enc->channels;
			m_header.AudioHeader.m_nFrames		= enc->frame_number;
			m_header.AudioHeader.m_nSampleRate	= enc->sample_rate;
			m_header.AudioHeader.m_nCodecID		= enc->codec_id;
			break;
		case CODEC_TYPE_VIDEO:
			m_nVsIndex = i;
			m_header.VideoHeader.m_nCodecID	= enc->codec_id;
			m_header.VideoHeader.m_nWidth	= enc->width;
			m_header.VideoHeader.m_nHeight	= enc->height;
			break;
		default:
			break;
		}
	}
	if ( m_nAsIndex < 0 && m_nVsIndex < 0)
	{
		return false;
	}
	return true;
}

bool NDFFMpegParse::ReadStream(BYTE **pBufferBlock, int& nSize)
{
	if (!m_bInit)
	{
		return false;
	}
	if (!m_pFmtCtx)
	{
		return false;
	}
	static AVPacket packet;
	memset(&packet, 0, sizeof(packet));

	int nRet = -1;
	nRet = av_read_frame(m_pFmtCtx, &packet);
	if (nRet >= 0)
	{
		*pBufferBlock =(BYTE*)&packet;
		return true;
	}
	else
	{
		return false;
	}
}
bool NDFFMpegParse::SeekStream(void* param)
{
	INT64 nTimeStamp	=	(INT64)(*(INT64*)param);
	int nRet = av_seek_frame(m_pFmtCtx, -1, nTimeStamp * 1000, AVSEEK_FLAG_BACKWARD|AVSEEK_FLAG_ANY);
	if (nRet >= 0)
	{
		return true;
	}
	return false;
}

bool NDFFMpegParse::ReadPreHeader(HEADER& header)
{
	header.m_nFlag	=	1;
	memcpy(&header, &m_header, sizeof(header));
	return false;
}